/*
 * @author       : Zy
 * @Description  : 陶晶驰串口屏显示实时路径
 * @Date         : 2025-05-24 22:15:26
 * @LastEditTime : 2025-07-28 01:15:01
 */
#include "HMI_UI.h"
// ===================== 串口配置 =====================
static UART_HandleTypeDef *activeHuart = &huart6; // 默认使用 USART6
/**
 * @brief 处理队列中的下一个命令
 */
void UART_ProcessNextCommand(void)
{
    if (cmdQueue.count > 0 && !uart_dma_busy)
    {
        // 复制命令到当前缓冲区
        memcpy(current_buffer, cmdQueue.buffer[cmdQueue.head], cmdQueue.lengths[cmdQueue.head]);
        uint16_t length = cmdQueue.lengths[cmdQueue.head];

        // 更新队列头部指针
        cmdQueue.head = (cmdQueue.head + 1) % MAX_CMD_QUEUE_SIZE;
        cmdQueue.count--;

        // 标记DMA为忙状态
        uart_dma_busy = 1;

        // 启动DMA传输
        HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(activeHuart, current_buffer, length);

        // 如果启动传输失败，重置忙标志
        if (status != HAL_OK)
        {
            uart_dma_busy = 0;
        }
    }
}
/**
 * @brief 将命令添加到队列
 *
 * @param cmd 命令字符串
 * @param length 命令长度
 * @return HAL_StatusTypeDef HAL库状态返回值
 */
HAL_StatusTypeDef UART_QueueCommand(const char *cmd, uint16_t length)
{
    if (length >= MAX_CMD_LENGTH)
    {
        return HAL_ERROR; // 命令太长
    }

    if (cmdQueue.count >= MAX_CMD_QUEUE_SIZE)
    {
        return HAL_BUSY; // 队列已满
    }

    // 添加命令到队列
    memcpy(cmdQueue.buffer[cmdQueue.tail], cmd, length);
    cmdQueue.lengths[cmdQueue.tail] = length;
    cmdQueue.tail = (cmdQueue.tail + 1) % MAX_CMD_QUEUE_SIZE;
    cmdQueue.count++;

    // 如果DMA当前不忙，立即处理下一个命令
    if (!uart_dma_busy)
    {
        UART_ProcessNextCommand();
    }

    return HAL_OK;
}
/**
 * @brief 格式化并发送通用串口命令（类似printf）
 */
HAL_StatusTypeDef HMI_Printf(const char *format, ...)
{
    char buffer[MAX_CMD_LENGTH];
    va_list args;
    int length;

    va_start(args, format);
    length = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    if (length < 0 || length >= sizeof(buffer))
    {
        return HAL_ERROR;
    }

    return UART_QueueCommand(buffer, length);
}

/**
 * @brief DMA传输完成回调函数，需要在HAL_UART_TxCpltCallback中调用
 */
void UART_DMA_TxCompleteCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART2)
    {
        uart_dma_busy = 0;

        // 检查队列中是否还有命令等待发送
        UART_ProcessNextCommand();
    }
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    UART_DMA_TxCompleteCallback(huart);
}

/**
 * @brief 初始化串口接收系统
 */
void HMI_Rx_Init(UART_HandleTypeDef *huart)
{
    if (huart != NULL)
    {
        activeHuart = huart;
    }
    // 清空缓冲区和处理器
    rxHead = 0;
    rxTail = 0;
    rxBusy = 0;
    numChannelHandlers = 0;

    // 启动接收中断
    HAL_UART_Receive_IT(activeHuart, &rxBuffer[rxHead], 1);
}
/**
 * @brief 注册通道回调函数
 *
 * @param channel 通道号
 * @param callback 回调函数
 * @return int 0成功，-1失败
 */
int HMI_Register_Call(int channel, ChannelCallback callback)
{
    if (numChannelHandlers >= MAX_CHANNELS)
    {
        return -1; // 回调函数注册已满
    }

    // 检查通道是否已注册，如果已注册则更新回调
    for (int i = 0; i < numChannelHandlers; i++)
    {
        if (channelHandlers[i].channel == channel)
        {
            channelHandlers[i].callback = callback;
            return 0;
        }
    }

    // 添加新通道回调
    channelHandlers[numChannelHandlers].channel = channel;
    channelHandlers[numChannelHandlers].callback = callback;
    numChannelHandlers++;

    return 0;
}
/**
 * @brief 处理接收到的数据，查找完整帧并调用回调
 */
void UART_ProcessReceivedData(void)
{
    static char cmdBuffer[UART_RX_BUFFER_SIZE];
    static uint16_t cmdIndex = 0;
    static uint8_t inFrame = 0;
    static uint8_t startMatched = 0;

    // 处理环形缓冲区中的所有数据
    while (rxHead != rxTail)
    {
        uint8_t c = rxBuffer[rxTail];
        rxTail = (rxTail + 1) % UART_RX_BUFFER_SIZE;

        // 处理起始序列匹配
        if (!inFrame)
        {
            // 检查起始序列匹配
            if ((startMatched == 0 && c == '@') ||
                (startMatched == 1 && c == '$') ||
                (startMatched == 2 && c == 'c') ||
                (startMatched == 3 && c == ':'))
            {
                startMatched++;
                if (startMatched == 4)
                { // 完整匹配起始序列
                    inFrame = 1;
                    cmdIndex = 0;
                    startMatched = 0;
                }
            }
            else
            {
                startMatched = 0; // 匹配失败，重置
            }
            continue;
        }

        // 帧结束符检测
        if (c == FRAME_END_CHAR)
        {
            cmdBuffer[cmdIndex] = '\0'; // 添加字符串结束符
            inFrame = 0;

            // 解析通道号和数据
            int channel;
            char *dataStr = NULL;

            if (sscanf(cmdBuffer, "%d,", &channel) == 1)
            {
                // 找到通道号后面的逗号
                dataStr = strchr(cmdBuffer, ',');
                if (dataStr)
                {
                    dataStr++; // 跳过逗号

                    // 查找并调用匹配的回调函数
                    for (uint8_t i = 0; i < numChannelHandlers; i++)
                    {
                        if (channelHandlers[i].channel == channel)
                        {
                            channelHandlers[i].callback(channel, dataStr);
                            break;
                        }
                    }
                }
            }
            continue;
        }

        // 接收到'\n'字符也认为帧结束
        if (c == '\n')
        {
            cmdBuffer[cmdIndex] = '\0';
            inFrame = 0;

            // 处理逻辑同上
            int channel;
            char *dataStr = NULL;

            if (sscanf(cmdBuffer, "%d,", &channel) == 1)
            {
                dataStr = strchr(cmdBuffer, ',');
                if (dataStr)
                {
                    dataStr++;

                    for (uint8_t i = 0; i < numChannelHandlers; i++)
                    {
                        if (channelHandlers[i].channel == channel)
                        {
                            channelHandlers[i].callback(channel, dataStr);
                            break;
                        }
                    }
                }
            }
            continue;
        }

        // 存储帧内数据
        if (inFrame && cmdIndex < UART_RX_BUFFER_SIZE - 1)
        {
            cmdBuffer[cmdIndex++] = c;
        }
    }
}

void HMI_Process(UART_HandleTypeDef *huart)
{
    if (huart == activeHuart)
    {
        // 更新接收缓冲区头指针
        rxHead = (rxHead + 1) % UART_RX_BUFFER_SIZE;

        // 如果缓冲区未满，继续接收
        if ((rxHead + 1) % UART_RX_BUFFER_SIZE != rxTail)
        {
            HAL_UART_Receive_IT(huart, &rxBuffer[rxHead], 1);
        }

        // 如果处理线程未运行，启动处理
        if (!rxBusy)
        {
            rxBusy = 1;
            UART_ProcessReceivedData();
            rxBusy = 0;
        }
    }
}